package com.rabbit.config;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.rabbit.constant.SecurityConstant;
import io.swagger.annotations.Api;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.ApiKeyVehicle;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

/**
 * <h1>Swagger配置</h1>
 *
 * @author zjw
 * @date 2022/02/14 21:27
 */
@Configuration
@EnableSwagger2WebMvc
@EnableKnife4j
@EnableConfigurationProperties(SwaggerProperties.class)
public class SwaggerConfig {

    @Resource
    private SwaggerProperties swaggerProperties;

    @Bean
    public Docket defaultApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(securitySchemes()).securityContexts(securityContexts());

    }

    /**
     * 配置基于 token 的鉴权对象
     */
    private List<ApiKey> securitySchemes() {
        return Collections.singletonList(new ApiKey(SecurityConstant.TOKEN_HEADER, SecurityConstant.TOKEN_HEADER, ApiKeyVehicle.HEADER.getValue()));
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .contact(new Contact(swaggerProperties.getName(), swaggerProperties.getUrl(), swaggerProperties.getEmail()))
                .version(swaggerProperties.getVersion())
                .build();
    }


    /**
     * 在 securityContexts 中通过正则表达式，设置需要使用参数的接口（或者说，是去除掉不需要使用参数的接口）
     */
    private List<SecurityContext> securityContexts() {
        return Collections.singletonList(SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("^.*$"))
                .build());
    }

    private List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Collections.singletonList(SecurityReference.builder()
                .reference(swaggerProperties.getAppId())
                .scopes(authorizationScopes).build());
    }
}
